<template>
  <el-popover v-model="showPopper" :trigger="trigger" :width="width" :placement="placement">
    <slot name="reference" slot="reference" />
    <el-empty :image-size="50" v-if="!data.length" />
    <div class="popover-select_wrap" v-else>
      <ul class="popover-select_list">
        <li
          class="popover-select_item"
          v-for="(item, index) in data"
          :key="index"
          :title="item[prop.label]"
          :class="{
            selected: selected.includes(item[prop.value]),
            disabled: item[prop.disabled]
          }"
          @click="toggle(item)"
        >
          {{ item[prop.label] }}
        </li>
      </ul>
      <div class="popover-select_btn">
        <el-button size="mini" type="primary" :disabled="!selected.length" @click="btnConfirm">
          {{ confirmButtonText }} {{ selected.length }}/{{ selectableTotal }}
        </el-button>
      </div>
    </div>
  </el-popover>
</template>
<script>
import { debounce } from '@/utils'
const triggerEnum = ['click', 'focus', 'hover', 'manual']
const defaultProps = { label: 'label', value: 'value', disabled: 'disabled' }
export default {
  name: 'PopoverSelect',
  props: {
    value: { type: Boolean, default: false },
    trigger: { type: String, default: 'click', validator: val => triggerEnum.includes(val) },
    width: { type: [String, Number], default: 200 },
    placement: { type: String, default: 'bottom' },
    props: { type: Object, default: () => defaultProps },
    data: { type: Array, default: () => [] },
    confirmButtonText: { type: String, default: '确认' }
  },
  data() {
    return {
      showPopper: false,
      selected: []
    }
  },
  computed: {
    prop() {
      return { ...defaultProps, ...this.props }
    },
    selectableTotal() {
      return this.data.filter(i => !i[this.prop.disabled]).length
    }
  },
  watch: {
    value: {
      immediate: true,
      handler(val) {
        this.showPopper = val
        this.$emit('input', val)
      }
    },
    showPopper(val) {
      this.selected = []
      this.$emit('input', val)
    }
  },
  created() {
    this.btnConfirm = debounce(this.confirm, 1e3, true)
  },
  methods: {
    toggle(item) {
      const { selected } = this
      const val = item[this.prop.value]
      const index = selected.findIndex(i => i === val)
      if (index > -1) selected.splice(index, 1)
      else selected.push(val)
    },
    confirm() {
      this.$emit('confirm', this.selected)
      this.showPopper = false
    }
  }
}
</script>
<style lang="scss" scoped>
.popover-select {
  &_wrap {
    margin: 0 -12px;
  }
  &_list {
    max-height: 300px;
    list-style: none;
    padding: 0;
    margin: 0;
    overflow-y: auto;
  }
  &_item {
    position: relative;
    color: #606266;
    font-size: 12px;
    line-height: 34px;
    padding: 0 40px 0 20px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    cursor: pointer;
    &:hover {
      background-color: #f5f7fa;
    }
    &.selected {
      color: #409eff;
      font-weight: 700;
      &::after {
        position: absolute;
        right: 20px;
        font-family: 'element-icons';
        content: '\e6da';
        font-size: 12px;
      }
    }
    &.disabled {
      color: #c0c4cc;
      cursor: not-allowed;
      pointer-events: none;
    }
  }
  &_btn {
    text-align: right;
    padding: 10px 20px 0;
  }
}
</style>
